package com.minidb.sql_compliler;

import java.util.ArrayList;
import java.util.List;

public class Lexer {

    //词法分析器
    public enum TokenType {
        KEYWORD, IDENTIFIER, NUMBER, STRING, SYMBOL, EOF
    }

    public static class Token {
        public TokenType type;
        public String value;
        public Token(TokenType type, String value) {
            this.type = type;
            this.value = value;
        }
        public String toString() {
            return type + "(" + value + ")";
        }
    }

    private String input;
    private int pos = 0;

    public Lexer(String input) {
        this.input = input;
    }

    public List<Token> tokenize(){
        List<Token> tokens = new ArrayList<>();
        while (pos < input.length()) {
            char current = input.charAt(pos);
            if (Character.isWhitespace(current)) {
                pos++;
            } else if (Character.isLetter(current)) {
                StringBuilder sb = new StringBuilder();
                while (pos < input.length() && (Character.isLetterOrDigit(input.charAt(pos)) || input.charAt(pos) == '_')) {
                    sb.append(input.charAt(pos++));
                }
                String word = sb.toString().toUpperCase();
                if (isKeyword(word)) {
                    tokens.add(new Token(TokenType.KEYWORD, word));
                } else {
                    tokens.add(new Token(TokenType.IDENTIFIER, word));
                }
            } else if (Character.isDigit(current)) {
                StringBuilder sb = new StringBuilder();
                while (pos < input.length() && Character.isDigit(input.charAt(pos))) {
                    sb.append(input.charAt(pos++));
                }
                tokens.add(new Token(TokenType.NUMBER, sb.toString()));
            } else if (current == '\'') {
                pos++; // skip opening quote
                StringBuilder sb = new StringBuilder();
                while (pos < input.length() && input.charAt(pos) != '\'') {
                    sb.append(input.charAt(pos++));
                }
                pos++; // skip closing quote
                tokens.add(new Token(TokenType.STRING, sb.toString()));
            } else {
                tokens.add(new Token(TokenType.SYMBOL, Character.toString(current)));
                pos++;
            }
        }
        tokens.add(new Token(TokenType.EOF, ""));
        return tokens;
    }

    private String readWhile(java.util.function.Predicate<Character> condition) {
        StringBuilder sb = new StringBuilder();
        while (pos < input.length() && condition.test(input.charAt(pos))) {
            sb.append(input.charAt(pos++));
        }
        return sb.toString();
    }

    private String readString(char quote) {
        pos++; // 跳过引导
        StringBuilder sb = new StringBuilder();
        while (pos < input.length() && input.charAt(pos) != quote) {
            sb.append(input.charAt(pos++));
        }
        pos++; // 跳过引导结束
        return sb.toString();
    }

    private boolean isKeyword(String word) {
        switch (word) {
            case "SELECT":
            case "FROM":
            case "WHERE":
            case "INSERT":
            case "INTO":
            case "VALUES":
            case "UPDATE":
            case "SET":
            case "DELETE":
            case "CREATE":
            case "TABLE":
            case "DROP":
                return true;
            default:
                return false;
        }
    }
}
